package com.tool_stdy.thread;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.google.common.util.concurrent.*;

/**
 * Created by yan_li on 2017/4/28.
 */
public class ListenFutureTest {

    public static void main(String[] args) throws Exception {
        // testListenFuture();
        should_test_furture();
    }

    public static void testListenFuture() {
        System.out.println("主任务执行完，开始异步执行副任务1.....");
        ListeningExecutorService pool = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(5));
        ListenableFuture<String> future = pool.submit(new Task());
        Futures.addCallback(future, new FutureCallback<String>() {
            @Override
            public void onSuccess(String result) {
                System.out.println("成功,结果是:" + result);
            }

            @Override
            public void onFailure(Throwable t) {
                System.out.println("出错,业务回滚或补偿");
            }
        });
        System.out.println("副本任务启动,回归主任务线,主业务正常返回2.....");
    }

    //transform
    public static void should_test_furture() throws Exception {
        ListeningExecutorService service = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(10));

        ListenableFuture future1 = service.submit(new Callable<Integer>() {
            public Integer call() throws InterruptedException {
                Thread.sleep(1000);
                System.out.println("call future 1.");
                return 1;
            }
        });

        ListenableFuture future2 = service.submit(new Callable<Integer>() {
            public Integer call() throws InterruptedException {
                Thread.sleep(1000);
                System.out.println("call future 2.");
                //       throw new RuntimeException("----call future 2.");
                return 1;
            }
        });

        final ListenableFuture allFutures = Futures.allAsList(future1, future2);
        final ListenableFuture transform = Futures.transform(allFutures, new AsyncFunction<List<String>, Boolean>() {
            @Override
            public ListenableFuture apply(List<String> results) throws Exception {
                System.out.println(JSON.toJSONString(results));
                //                SettableFuture<String> listenableFuture = SettableFuture.create();
                //                listenableFuture.set("hah"); //为ListenableFuture设置特定的返回值
                //                return listenableFuture;

                return Futures.immediateFuture(String.format("success future:%d", results.size()));
            }
        });

        Futures.addCallback(transform, new FutureCallback<Object>() {

            public void onSuccess(Object result) {
                System.out.println(result.getClass());
                System.out.printf("success with: %s%n", result);
            }

            public void onFailure(Throwable thrown) {
                System.out.printf("onFailure%s%n", thrown.getMessage());
            }
        });

        System.out.println(transform.get());
    }
}

class Task implements Callable<String> {

    @Override
    public String call() throws Exception {
        TimeUnit.SECONDS.sleep(1);
        int a = 1 / 0;
        return "task done";
    }
}
